package com.soft.service.impl;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.soft.entity.Kanban;
import com.soft.entity.KanbanColumn;
import com.soft.entity.KanbanItem;
import com.soft.mapper.KanbanColumnMapper;
import com.soft.mapper.KanbanItemMapper;
import com.soft.mapper.KanbanMapper;
import com.soft.service.KanbanService;

/**
 * 看板服务实现：包含默认列创建、详情聚合、卡片排序与列移动、
 * 与日程状态互相同步、以及删除时的级联清理与重排。
 */
@Service
public class KanbanServiceImpl implements KanbanService {

    @Autowired
    private KanbanMapper kanbanMapper;
    
    @Autowired
    private KanbanColumnMapper kanbanColumnMapper;
    
    @Autowired
    private KanbanItemMapper kanbanItemMapper;
    
    @Override
    public List<Kanban> getAllKanbans() {
        return kanbanMapper.selectList(null);
    }
    

    @Override
    public List<Kanban> getKanbansByTeamId(Integer teamId) {
        QueryWrapper<Kanban> wrapper = new QueryWrapper<>();
        wrapper.eq("team_id", teamId);
        return kanbanMapper.selectList(wrapper);
    }
    
    @Override
    public List<Kanban> getKanbansByUserId(Integer userId) {
        // 获取用户相关的所有看板：
        // 1. 用户创建的看板
        // 2. 用户所在团队的看板（子查询）
        QueryWrapper<Kanban> wrapper = new QueryWrapper<>();
        wrapper.eq("creator_id", userId)
               .or()
               .inSql("team_id",
                   "SELECT team_id FROM team_member WHERE user_id = " + userId + " AND status = 'active'");
        return kanbanMapper.selectList(wrapper);
    }

    @Override
    @Transactional
    public Kanban createKanban(Kanban kanban) {
    // 1) 记录创建时间（用于排序/审计）
        kanban.setCreateTime(LocalDateTime.now());
        kanbanMapper.insert(kanban);
        
    // 2) 创建默认列：待办/进行中/已完成，降低前端初始化成本
        createDefaultColumns(kanban.getKanbanId());
        
        return kanban;
    }

    /** 新建看板时创建默认三列：待办/进行中/已完成 */
    private void createDefaultColumns(Integer kanbanId) {
        String[] defaultColumns = {"待办", "进行中", "已完成"};
        for (int i = 0; i < defaultColumns.length; i++) {
            KanbanColumn column = new KanbanColumn();
            column.setKanbanId(kanbanId);
            column.setColumnName(defaultColumns[i]);
            column.setSortOrder(i + 1);
            kanbanColumnMapper.insert(column);
        }
    }

    @Override
    public Map<String, Object> getKanbanDetail(Integer kanbanId) {
        Map<String, Object> result = new HashMap<>();
        
    // 1) 获取看板基本信息
        Kanban kanban = kanbanMapper.selectById(kanbanId);
        result.put("kanban", kanban);
        
    // 2) 获取看板列，并按 sort_order 升序
        QueryWrapper<KanbanColumn> columnWrapper = new QueryWrapper<>();
        columnWrapper.eq("kanban_id", kanbanId);
        columnWrapper.orderByAsc("sort_order");
        List<KanbanColumn> columns = kanbanColumnMapper.selectList(columnWrapper);
        result.put("columns", columns);
        
    // 3) 获取看板卡片（关联日程信息），用于一次性渲染
    List<Map<String, Object>> items = kanbanItemMapper.getItemsWithSchedule(kanbanId);
    // 前端期望字段：itemId, kanbanId, scheduleId, columnId, assigneeId, assignTime, sortOrder,
    // schedule_title, schedule_status, schedule_priority, assignee_name
    result.put("items", items);
        
        return result;
    }

    @Override
    public KanbanColumn addColumn(KanbanColumn column) {
    // 1) 获取当前最大排序号，用于分配下一序号
        QueryWrapper<KanbanColumn> wrapper = new QueryWrapper<>();
        wrapper.eq("kanban_id", column.getKanbanId());
        wrapper.orderByDesc("sort_order");
        wrapper.last("LIMIT 1");
        KanbanColumn lastColumn = kanbanColumnMapper.selectOne(wrapper);
        
        int nextSortOrder = lastColumn != null ? lastColumn.getSortOrder() + 1 : 1;
        column.setSortOrder(nextSortOrder);
        
        kanbanColumnMapper.insert(column);
        return column;
    }

    @Override
    @Transactional
    /** 移动卡片：重排目标列，更新卡片位置，并按列名推导状态更新日程 */
    public void moveItem(Integer itemId, Integer newColumnId, Integer newSortOrder) {
        KanbanItem item = kanbanItemMapper.selectById(itemId);
        if (item == null) {
            throw new RuntimeException("卡片不存在");
        }
        
    // 1) 更新目标列中的其他卡片排序：为插入位置预留空间
        kanbanItemMapper.updateSortOrdersAfterMove(newColumnId, newSortOrder);
        
    // 2) 更新当前卡片的列与序号
        item.setColumnId(newColumnId);
        item.setSortOrder(newSortOrder);
        kanbanItemMapper.updateById(item);

    // 3) 根据目标列名同步日程状态（列与状态紧密关联）
        if (item.getScheduleId() != null) {
            KanbanColumn targetCol = kanbanColumnMapper.selectById(newColumnId);
            String status = resolveStatusByColumnName(targetCol != null ? targetCol.getColumnName() : null);
            if (status != null) {
                kanbanItemMapper.updateScheduleStatus(item.getScheduleId(), status);
            }
        }
    }

    @Override
    /** 添加卡片：未指定列则放到首列，排序号接在末尾 */
    public KanbanItem addItem(KanbanItem item) {
    // 1) 如果未指定列，获取第一列作为默认列
        if (item.getColumnId() == null) {
            QueryWrapper<KanbanColumn> columnWrapper = new QueryWrapper<>();
            columnWrapper.eq("kanban_id", item.getKanbanId());
            columnWrapper.orderByAsc("sort_order");
            columnWrapper.last("LIMIT 1");
            KanbanColumn firstCol = kanbanColumnMapper.selectOne(columnWrapper);
            if (firstCol == null) {
                throw new RuntimeException("看板没有可用的列");
            }
            item.setColumnId(firstCol.getColumnId());
        } else {
            KanbanColumn existsCol = kanbanColumnMapper.selectById(item.getColumnId());
            if (existsCol == null) {
                throw new RuntimeException("指定列不存在");
            }
        }
        
    // 2) 获取该列最大排序号，插入到尾部
        QueryWrapper<KanbanItem> itemWrapper = new QueryWrapper<>();
    itemWrapper.eq("column_id", item.getColumnId());
        itemWrapper.orderByDesc("sort_order");
        itemWrapper.last("LIMIT 1");
        KanbanItem lastItem = kanbanItemMapper.selectOne(itemWrapper);
        
        int nextSortOrder = lastItem != null ? lastItem.getSortOrder() + 1 : 1;
        item.setSortOrder(nextSortOrder);
        
    // 3) 插入记录
    kanbanItemMapper.insert(item);
        return item;
    }

    @Override
    public void assignItem(Integer itemId, Integer assigneeId) {
        KanbanItem item = kanbanItemMapper.selectById(itemId);
        if (item == null) {
            throw new RuntimeException("卡片不存在");
        }
        
        item.setAssigneeId(assigneeId);
        item.setAssignTime(LocalDateTime.now());
        kanbanItemMapper.updateById(item);
    }

    @Override
    @Transactional
    /** 根据日程状态，将关联卡片移动到对应列（名称匹配→索引回退） */
    public void syncItemColumnWithStatus(Integer scheduleId, String status) {
        if (scheduleId == null || status == null || status.trim().isEmpty()) {
            return;
        }
        // 1) 找到该日程关联的所有看板卡片
        QueryWrapper<KanbanItem> itemQ = new QueryWrapper<>();
        itemQ.eq("schedule_id", scheduleId);
        List<KanbanItem> items = kanbanItemMapper.selectList(itemQ);
        if (items == null || items.isEmpty()) {
            return; // 没有关联卡片，忽略
        }

        for (KanbanItem item : items) {
            // 2) 拉取该看板的列，按排序
            QueryWrapper<KanbanColumn> colQ = new QueryWrapper<>();
            colQ.eq("kanban_id", item.getKanbanId());
            colQ.orderByAsc("sort_order");
            List<KanbanColumn> cols = kanbanColumnMapper.selectList(colQ);
            if (cols == null || cols.isEmpty()) {
                continue;
            }

            // 3) 目标列：先按名称匹配（中文/英文常见别名），否则按索引回退
            Integer targetColumnId = resolveTargetColumnId(cols, status);
            if (targetColumnId == null) {
                continue;
            }

            if (targetColumnId.equals(item.getColumnId())) {
                continue; // 已在目标列
            }

            // 4) 计算目标列尾部下一个 sortOrder
            QueryWrapper<KanbanItem> tailQ = new QueryWrapper<>();
            tailQ.eq("column_id", targetColumnId).orderByDesc("sort_order").last("LIMIT 1");
            KanbanItem last = kanbanItemMapper.selectOne(tailQ);
            int nextOrder = last != null ? last.getSortOrder() + 1 : 1;

            // 5) 执行更新
            item.setColumnId(targetColumnId);
            item.setSortOrder(nextOrder);
            kanbanItemMapper.updateById(item);
        }
    }

    /** 根据状态解析目标列ID：优先名称匹配，否则按索引回退 */
    private Integer resolveTargetColumnId(List<KanbanColumn> cols, String status) {
        String st = status.toLowerCase();
        // 名称映射（忽略大小写、空格）
        for (KanbanColumn c : cols) {
            String name = c.getColumnName();
            if (name == null) continue;
            String n = name.replaceAll("\\s+", "").toLowerCase();
            if (st.equals("todo") && (n.contains("待办") || n.contains("todo") || n.contains("backlog"))) {
                return c.getColumnId();
            }
            if (st.equals("doing") && (n.contains("进行中") || n.contains("doing") || n.contains("inprogress") || n.contains("progress"))) {
                return c.getColumnId();
            }
            if (st.equals("done") && (n.contains("已完成") || n.contains("完成") || n.equals("done") || n.contains("完成") || n.contains("done"))) {
                return c.getColumnId();
            }
        }
        // 索引回退：todo→第1列，doing→第2列，done→最后一列
        if ("todo".equals(st)) return cols.get(0).getColumnId();
        if ("doing".equals(st) && cols.size() >= 2) return cols.get(1).getColumnId();
        if ("done".equals(st)) return cols.get(cols.size() - 1).getColumnId();
        return null;
    }

    /**
     * 反向映射：根据列名推导日程状态（todo/doing/done）。无法判断则返回 null。
     */
    private String resolveStatusByColumnName(String columnName) {
        if (columnName == null) return null;
        String n = columnName.replaceAll("\\s+", "").toLowerCase();
        if (n.contains("待办") || n.contains("todo") || n.contains("backlog")) return "todo";
        if (n.contains("进行中") || n.contains("doing") || n.contains("inprogress") || n.contains("progress")) return "doing";
        if (n.contains("已完成") || n.contains("完成") || n.equals("done") || n.contains("done")) return "done";
        return null;
    }

    @Override
    @Transactional
    public void deleteKanban(Integer kanbanId) {
    // 1) 删除看板卡片
        QueryWrapper<KanbanItem> itemWrapper = new QueryWrapper<>();
        itemWrapper.eq("kanban_id", kanbanId);
        kanbanItemMapper.delete(itemWrapper);
        
    // 2) 删除看板列
        QueryWrapper<KanbanColumn> columnWrapper = new QueryWrapper<>();
        columnWrapper.eq("kanban_id", kanbanId);
        kanbanColumnMapper.delete(columnWrapper);
        
    // 3) 删除看板
        kanbanMapper.deleteById(kanbanId);
    }

    @Override
    @Transactional
    public void deleteColumn(Integer columnId) {
        KanbanColumn col = kanbanColumnMapper.selectById(columnId);
        if (col == null) {
            throw new RuntimeException("列不存在");
        }
    // 1) 删除该列下卡片
        QueryWrapper<KanbanItem> itemsQ = new QueryWrapper<>();
        itemsQ.eq("column_id", columnId);
        kanbanItemMapper.delete(itemsQ);

    // 2) 删除列
        kanbanColumnMapper.deleteById(columnId);

    // 3) 重排同看板剩余列 sortOrder，保持连续性
        QueryWrapper<KanbanColumn> colsQ = new QueryWrapper<>();
        colsQ.eq("kanban_id", col.getKanbanId());
        colsQ.orderByAsc("sort_order");
        List<KanbanColumn> left = kanbanColumnMapper.selectList(colsQ);
        int order = 1;
        for (KanbanColumn c : left) {
            if (c.getSortOrder() == null || c.getSortOrder() != order) {
                c.setSortOrder(order);
                kanbanColumnMapper.updateById(c);
            }
            order++;
        }
    }

    @Override
    public void updateKanban(Integer kanbanId, String kanbanName, String description) {
        Kanban kb = kanbanMapper.selectById(kanbanId);
        if (kb == null) {
            throw new RuntimeException("看板不存在");
        }
        boolean changed = false; // 标记是否有变更，避免无差异更新
        if (kanbanName != null && !kanbanName.trim().isEmpty()) {
            kb.setKanbanName(kanbanName.trim());
            changed = true;
        }
        if (description != null) {
            kb.setDescription(description);
            changed = true;
        }
        if (changed) {
            kanbanMapper.updateById(kb); // 仅在变更时落库
        }
    }
    
    @Override
    public void removeItemByScheduleId(Integer scheduleId) {
    // 批量删除关联指定日程的卡片
        QueryWrapper<KanbanItem> wrapper = new QueryWrapper<>();
        wrapper.eq("schedule_id", scheduleId);
        kanbanItemMapper.delete(wrapper);
    }
    
    @Override
    public List<Kanban> getManagedKanbans(Integer userId) {
    // 查询用户管理的团队看板（用户是团队领导者的看板）
        QueryWrapper<Kanban> wrapper = new QueryWrapper<>();
        wrapper.inSql("team_id", 
            "SELECT team_id FROM team_member WHERE user_id = " + userId + " AND team_role = 'leader' AND status = 'active'");
        return kanbanMapper.selectList(wrapper);
    }
    
    @Override
    public List<Kanban> getJoinedKanbans(Integer userId) {
    // 查询用户参加的团队看板（用户是团队成员但非领导者的看板）
        QueryWrapper<Kanban> wrapper = new QueryWrapper<>();
        wrapper.inSql("team_id", 
            "SELECT team_id FROM team_member WHERE user_id = " + userId + " AND team_role = 'member' AND status = 'active'");
        return kanbanMapper.selectList(wrapper);
    }
}
